package crypto;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;

import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAtest {
    //前端用公钥加密，加密后是byte流，所以要base64转换成可读形式
    public String encrypt(String rawText, String publicKeyPath, String transformation, String encoding)
            throws IOException, GeneralSecurityException {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(IOUtils.toByteArray(new FileInputStream(publicKeyPath)));
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec));
        return Base64.encodeBase64String(cipher.doFinal(rawText.getBytes(encoding)));
    }

    //后端用私钥解密  由于解密后已是明文String的byte[]形式
    public String decrypt(String cipherText, String privateKeyPath, String transformation, String encoding)
            throws IOException, GeneralSecurityException {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(IOUtils.toByteArray(new FileInputStream(privateKeyPath)));
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.DECRYPT_MODE, KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec));
        return new String(cipher.doFinal(Base64.decodeBase64(cipherText)), encoding);
    }

    //做签名。私钥加密，公钥解密
    public String sign(String rawText, byte [] privateKey, String transformation, String encoding)
            throws IOException, GeneralSecurityException {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec));
        return Base64.encodeBase64String(cipher.doFinal(rawText.getBytes(encoding)));
    }

    //验签。公钥解密
    public String checkSign(String cipherText, String publicKeyPath, String transformation, String encoding)
            throws IOException, GeneralSecurityException {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(IOUtils.toByteArray(new FileInputStream(publicKeyPath)));
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.DECRYPT_MODE, KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec));
        return new String(cipher.doFinal(Base64.decodeBase64(cipherText)), encoding);
    }


    public static void main(String[] args) throws IOException, GeneralSecurityException {
        RSAtest RSA = new RSAtest();
        //文件路径使用相对路径，保证不同环境可以顺利执行
        String privateKeyPathName = "src/main/resources/RSA/pkcs8_private.key";
        String publicKeyPathName = "src/main/resources/RSA/public.key";

        String transformation = "RSA/ECB/PKCS1Padding";
        String encoding = "UTF-8";
        String rawText = " 2.John has a long mustache too; 3.John has a long mustache too; 4.John has a long mustache too; 5.John has a long mustache too; 6.John has a long mustache too; 7.John has a long mustache too; 8.John has a ;";

        byte[] privatekeybyte = getPrivateKey();

        String encrypted = RSA.encrypt(rawText, publicKeyPathName, transformation, encoding);
        System.out.println("encrypted string: " + encrypted);

        String decrypted = RSA.decrypt(encrypted, privateKeyPathName, transformation, encoding);
        System.out.println("decrypted string: " + decrypted);


        String signResult = RSA.sign(rawText, privatekeybyte, transformation, encoding);
        System.out.println("encrypted string: " + signResult);

        String unsignResult = RSA.checkSign(signResult, publicKeyPathName, transformation, encoding);
        System.out.println("decrypted string: " + unsignResult);
    }


    private static byte[] getPrivateKey() {
        String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/8/75XWfZYCpGqKYCdMZS3K/w\n" +
                "8iOcB0yKscd9R8sF9fdWFIlBV1QDx51U7pEMOoZaRpRtigis1HOFA/bBKXrwt/x25W3q6VYjD3ZG\n" +
                "rc0TdaWlfzGVnob0XPTGqD1B/zh3srD4w1FAHbpdsMrdtjTsozhkbQneavFrQl8kj7+91oVbWiAg\n" +
                "vKuqsXQLMhRJp3HwauzQff+R+jH/g8r0Pn2shk2kVQU+IQYMhUfC4w+IDpbIydDShmeLjjtKzmio\n" +
                "0gzVLFFOd47mY23KiFqDK6QwTc+mJCjiDShW5pGSn1P8hbNxOBVkcV+x5g14hsThRDfmC3MgnGrU\n" +
                "ta/OnSXA+LclAgMBAAECggEAYosz0fcm8kzRR1cbatViX3XWiV718ws4O1fLb0ClNNkycim20Smx\n" +
                "AwO+fLTBGEMPaFclqhqcG4YyDA6d5kqSR/Rckvlz9Y523yb39I8TYjMaqBzlasdoxxjVvQrv7+rD\n" +
                "pYfCHOPA2aapX6H8c9gv0XB16fCkiV/jssnvKEj4Cc+sGdB+vaJNKhh1dl+swlNMBfEWEjU/YEy5\n" +
                "0QwRuUoMb8yK5iHPHFB8hSAYvbaKZwoG09veeEkxHyEfh+uHLUgoMhWVOO310sEIdFwl6ywrC8rQ\n" +
                "KfN4zn6j4UH/Y2VGB+jxowF6gsn9ygMbl9fnjhyT+xF5utPDQcpBPjQIZd1NgQKBgQD0H9iDQVV/\n" +
                "6n1Q3c4LSiKh7qmLsJIBKkML00JU7Aw6yLM0/5F8MFtjiJToP8nfhjtYCWFjO2NjLXdCaVvKVUqe\n" +
                "PQpem7rQwx4fSiT3AGck7AICOUYwd5/u4yz25KYx6VU0wZvWxZKt5iDFV3eiwkOMDuwzx8WXpQgV\n" +
                "3VJnR7+a4QKBgQDJSnIQTEz3sB8UV2AZsSO4ihE2H/MqGzMyB3mxN/V39n80C6sQPUraGd3mWaDC\n" +
                "4lQvkaKmCB2cln/8D5J528VLxjiczEN7dLePRdF6qYDr1Iu/Y4LNikI7RXbPCm5UPxHlPwN6R5PH\n" +
                "6jbmdGFCoELIrjqE5bSu8OilVFtw3x+IxQKBgQDZxDKiWzyGv8kLwuBTB82+/6O0XUzQxz9JpCku\n" +
                "keYS5geeRkAkNQrAzgxu5MASqa30SWHbYBW3Wc5hqpRb+Bt47mB6ppZONU+Af+Zbg7t+nxznmOm4\n" +
                "wG0lbvckQjDSox8D0ZVPT60ZfQhMoUqyIHKa1JD1W8YyEOAWiPhB8ynDYQKBgF6oXplheDRmI0dq\n" +
                "i2upjJXEf7GHNs+POPUG5Og823dNeKYd8pTRbfjAf0RK07mxu0sfXnBbkqlHcOo03HnnqpEmpwq9\n" +
                "V+KfkY6Tk53uRg0gx5L6FdHYearr0KIuUpHVkvHOPzFqpYk2kBixk+dD/APpQuWqK9y0t4K/97xN\n" +
                "gMPNAoGARfxvEtEAdJDniAjFYZpOznd/aI3sqZysdXWkk4MTgVBiTx1fyJhBVHL1ZyTaAsfDd0It\n" +
                "SpBXku3/3jxMHbbBzM905t09HjbcnRwELI20GoBh+eJ+UDTD6V6mh7Bav16QKRK5CdniYe0zAOKt\n" +
                "ucgAGf3F7zfIO8oH/jQsdykzQ60=";
        return Base64.decodeBase64(privateKey);
    }
    private static byte[] getPublicKey(){
        String publickey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv/P++V1n2WAqRqimAnTGUtyv8PIjnAdM\n" +
                "irHHfUfLBfX3VhSJQVdUA8edVO6RDDqGWkaUbYoIrNRzhQP2wSl68Lf8duVt6ulWIw92Rq3NE3Wl\n" +
                "pX8xlZ6G9Fz0xqg9Qf84d7Kw+MNRQB26XbDK3bY07KM4ZG0J3mrxa0JfJI+/vdaFW1ogILyrqrF0\n" +
                "CzIUSadx8Grs0H3/kfox/4PK9D59rIZNpFUFPiEGDIVHwuMPiA6WyMnQ0oZni447Ss5oqNIM1SxR\n" +
                "TneO5mNtyohagyukME3PpiQo4g0oVuaRkp9T/IWzcTgVZHFfseYNeIbE4UQ35gtzIJxq1LWvzp0l\n" +
                "wPi3JQIDAQAB\n";
        return Base64.decodeBase64(publickey);
    }
}
